var express = require('express');
var router = express.Router();
var request = require('request');

var CommonJS = require('../../../common/common');
var DBConfig = require('../../../db/dbconfig');
var Wx_config = require('../../../wx_config/wx_config');
var mysql = require('mysql');
var pool = mysql.createPool(DBConfig.mysql2);

var cryptoMO = require('crypto');
var parseString = require('xml2js').parseString;
var fs = require('fs');

var key = Wx_config.Mch_key;

// 支付成功发送模板消息
function sendMessage(open_id,form_id,pay_time,order_no,pay_amount){
	var template_id = "wTFhpMmfbHo6KoehgAf0MfK2vLdPoOd1RjgsRFPM7b4";
	var postData = {
	  touser: open_id,
      template_id: template_id,
      page: 'pages/index/index',
      form_id: form_id,
      data: {
        keyword1: {
          value: pay_time,
          color: "#173177"
        },
        keyword2: {
          value: order_no,
          color: "#173177"
        },
        keyword3: {
          value: pay_amount + '元',
          color: "#173177"
        }
      }
	}
	postData = JSON.stringify(postData);
	var urlStr = 'http://localhost:8100/jkyx/access_token';
	request(urlStr, function (error, response, body) {
		if (!error && response.statusCode == 200) {
			var body = JSON.parse(body);
			var access_token = body.access_token;
				var postStr = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=' + access_token;
				request({
					url: postStr,
					method: 'post',
					body: postData
				}, function (error, response, body) {
					if (!error && response.statusCode == 200) {
						console.log(body);
					}
				})
		}
	})
}


// 支付成功
router.get('/jkyx/pay_success', function(req, res, next) {
	var param = req.query || req.params; 
	var account_id = param.account_id;
	var recharge_pay_amount = param.recharge_pay_amount || 0; // 余额支付金额
	var pay_amount_other = param.pay_amount_other || 0; // 微信支付金额
	var pay_timer = CommonJS.getNowFormatDate();  // 支付时间
	var order_no = param.order_no || ''; // 商户订单号
	var balance = param.balance || 0; // 用户账户余额
	
	var open_id = param.open_id || ''; // 微信openid
	var form_id = param.form_id || ''; // 模板消息form_id
	var pay_time = param.pay_time || CommonJS.getNowFormatDate(); // 支付时间
	var pay_amount = param.pay_amount || ''; // 订单金额
	sendMessage(open_id,form_id,pay_time,order_no,pay_amount);
	

	var payment_id = 1;
	// 没有使用余额支付
	if (recharge_pay_amount == 0) {
		payment_id = 1; // 微信支付
	} else{
		if (pay_amount_other == 0) {
			payment_id = 3; // 余额支付
		} else{
			payment_id = 6; // 微信 余额 混合支付
		}
	}
	balance = Number(balance) - Number(recharge_pay_amount);
	pool.getConnection(function(err, connection) {
		if(err){
			res.end(JSON.stringify({
     			msg: '数据库连接失败',
     			status:'101',
     		}));
		}
		switch (payment_id){
			case 1: // 微信支付
				var urlStr = 'http://localhost:8100/jkyx/wxpay_orderQuery?out_trade_no=' + order_no;
				request(urlStr, function (error, response, body) {
					if (!error && response.statusCode == 200) {
						var body = JSON.parse(body);
						var transaction_id = body.result.xml.transaction_id[0] || '';
						connection.query(DBConfig.paySuccess,[payment_id,recharge_pay_amount,pay_amount_other,pay_timer,pay_timer,transaction_id,account_id,order_no,account_id],function (err, results) {
							connection.release();
							if (err){
							  	res.end(JSON.stringify({
					     			msg: '数据库查询失败',
					     			status:'102',
					     			err: err
					     		}));
							}else{
								res.end(JSON.stringify({
					     			msg: '操作成功',
					     			status:'100',
					     		}));	         
							}
						})
					}
				})
				break;
			case 3: // 余额支付
				var transaction_id = '';
				connection.query(DBConfig.paySuccess2,[payment_id,recharge_pay_amount,pay_amount_other,pay_timer,pay_timer,transaction_id,account_id,order_no,balance,account_id,account_id,recharge_pay_amount,pay_timer,order_no],function (err, results) {
					connection.release(); 
					if (err){
					  	res.end(JSON.stringify({
			     			msg: '数据库查询失败',
			     			status:'102',
			     			err: err
			     		}));
					}else{
						res.end(JSON.stringify({
			     			msg: '操作成功',
			     			status:'100',
			     		}));	         
					}
				})
				break;
			case 6: // 混合支付
				var urlStr = 'http://localhost:8100/jkyx/wxpay_orderQuery?out_trade_no=' + order_no;
				request(urlStr, function (error, response, body) {
					if (!error && response.statusCode == 200) {
						var body = JSON.parse(body);
						var transaction_id = body.result.xml.transaction_id[0] || '';
						connection.query(DBConfig.paySuccess2,[payment_id,recharge_pay_amount,pay_amount_other,pay_timer,pay_timer,transaction_id,account_id,order_no,balance,account_id,account_id,recharge_pay_amount,pay_timer],function (err, results) {
							connection.release();
							if (err){
							  	res.end(JSON.stringify({
					     			msg: '数据库查询失败',
					     			status:'102',
					     			err: err
					     		}));
							}else{
								res.end(JSON.stringify({
					     			msg: '操作成功',
					     			status:'100',
					     		}));	         
							}
						})
					}
				})
				break;
			default:
				break;
		}
	})
});
// 支付失败
router.get('/jkyx/pay_fail', function(req, res, next) {
	var param = req.query || req.params; 
	var account_id = param.account_id;
	var recharge_pay_amount = param.recharge_pay_amount || 0; // 余额支付金额
	var pay_amount_other = param.pay_amount_other || 0; // 微信支付金额
	var pay_timer = CommonJS.getNowFormatDate();  // 支付事件
	var order_no = param.order_no || ''; // 商户订单号
	var balance = param.balance || 0; // 用户账户余额
	
	var payment_id = 1;
	// 没有使用余额支付
	if (recharge_pay_amount == 0) {
		payment_id = 1; // 微信支付
	} else{
		if (pay_amount_other == 0) {
			payment_id = 3; // 余额支付
		} else{
			payment_id = 6; // 微信 余额 混合支付
		}
	}
	balance = Number(balance) - Number(recharge_pay_amount);
	pool.getConnection(function(err, connection) {
		if(err){
			res.end(JSON.stringify({
     			msg: '数据库连接失败',
     			status:'101',
     		}));
		}
		connection.query(DBConfig.payFail,[payment_id,recharge_pay_amount,pay_amount_other,pay_timer,account_id,order_no],function (err, results) {
			connection.release();
			if (err){
			  	res.end(JSON.stringify({
	     			msg: '数据库查询失败',
	     			status:'102',
	     			err: err
	     		}));
			}else{
				res.end(JSON.stringify({
	     			msg: '操作成功',
	     			status:'100',
	     		}));	         
			}
		})
	})
});
// 充值成功
router.get('/jkyx/recharge_success', function(req, res, next) {
	var param = req.query || req.params; 
	var account_id = param.account_id;
	var recharge_amount = param.recharge_amount || 0; // 余额支付金额
	var balance = param.balance || 0; // 用户账户余额
	var order_no = param.order_no || '';
	
	balance = Number(balance) + Number(recharge_amount);
	var create_time = CommonJS.getNowFormatDate();
	var urlStr = 'http://localhost:8100/jkyx/wxpay_orderQuery?out_trade_no=' + order_no;
	request(urlStr, function (error, response, body) {
		if (!error && response.statusCode == 200) {
			var body = JSON.parse(body);
			var transaction_id = body.result.xml.transaction_id[0] || '';
			pool.getConnection(function(err, connection) {
				if(err){
					res.end(JSON.stringify({
		     			msg: '数据库连接失败',
		     			status:'101',
		     		}));
				}
				connection.query(DBConfig.rechargeSuccess,[balance,account_id,account_id,recharge_amount,create_time,order_no,transaction_id],function (err, results) {
					connection.release();
					if (err){
					  	res.end(JSON.stringify({
			     			msg: '数据库查询失败',
			     			status:'102',
			     			err: err
			     		}));
					}else{
						res.end(JSON.stringify({
			     			msg: '操作成功',
			     			status:'100',
			     		}));	         
					}
				})
			})
		}
	})
});

/*
 * 根据openid 发起微信支付    
 */
router.get('/jkyx/wxpay_unifiedorder', function(req, res, next) {
	var param = req.query || req.params; 
	var openid = param.open_id; // 用户openid
	var account_id = param.account_id; // 用户ID
	var order_no = param.order_no || Wx_config.getWxPayOrdrID(); // 生成订单号; 
	var pay_amount_other = param.pay_amount_other; // 微信支付金额
	
	
	var spbill_create_ip = req.ip.replace(/::ffff:/, ''); // 获取客户端ip
	spbill_create_ip = '183.94.25.22'
	var body = '吉客优鲜商城订单支付'; // 商品描述
	var notify_url = 'https://c.jackfresh.cn/jkyx/wxpay' // 支付成功的回调地址  可访问 不带参数
	var nonce_str = getNonceStr(); // 随机字符串
	var out_trade_no = order_no; // 商户订单号
	var total_fee = pay_amount_other; // 订单价格 单位是 分
	total_fee = 1;
	var timestamp = Math.round(new Date().getTime()/1000); // 当前时间
	
	var bodyData = '<xml>';
	bodyData += '<appid>' + Wx_config.AppID + '</appid>';  // 小程序ID
	bodyData += '<body>' + body + '</body>'; // 商品描述
	bodyData += '<mch_id>' + Wx_config.Mch_id + '</mch_id>'; // 商户号
	bodyData += '<nonce_str>' + nonce_str + '</nonce_str>'; // 随机字符串
	bodyData += '<notify_url>' + notify_url + '</notify_url>'; // 支付成功的回调地址 
	bodyData += '<openid>' + openid + '</openid>'; // 用户标识
	bodyData += '<out_trade_no>' + out_trade_no + '</out_trade_no>'; // 商户订单号
	bodyData += '<spbill_create_ip>' + spbill_create_ip + '</spbill_create_ip>'; // 终端IP
	bodyData += '<total_fee>' + total_fee + '</total_fee>'; // 总金额 单位为分
	bodyData += '<trade_type>JSAPI</trade_type>'; // 交易类型 小程序取值如下：JSAPI
	// 签名
	var sign = paysignjsapi(
		Wx_config.AppID,
		body, 
		Wx_config.Mch_id, 
		nonce_str,
		notify_url, 
		openid, 
		out_trade_no, 
		spbill_create_ip, 
		total_fee
	);
	bodyData += '<sign>' + sign + '</sign>';
	bodyData += '</xml>';
	// 微信小程序统一下单接口
	var urlStr = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
	request({
		url: urlStr,
		method: 'POST',
		body: bodyData
	}, function (error, response, body) {
		if (!error && response.statusCode == 200) {
			var returnValue = {};
			parseString(body, function (err, result) {
				if (result.xml.return_code.length > 0) {
					if (result.xml.return_code[0] == 'SUCCESS') {
						returnValue.msg = '操作成功';
						returnValue.status = '100';
						returnValue.out_trade_no = out_trade_no;  // 商户订单号
						// 小程序 客户端支付需要 nonceStr,timestamp,package,paySign  这四个参数
						returnValue.nonceStr = result.xml.nonce_str[0]; // 随机字符串
						returnValue.timestamp = timestamp.toString(); // 时间戳
						returnValue.package = 'prepay_id=' + result.xml.prepay_id[0]; // 统一下单接口返回的 prepay_id 参数值
						returnValue.paySign = paysignjs(Wx_config.AppID, returnValue.nonceStr, returnValue.package, 'MD5',timestamp); // 签名
					    returnValue.order_no = order_no;
					    returnValue.payTime = CommonJS.getNowFormatDate();
					    returnValue.prepay_id = result.xml.prepay_id[0];
					    res.end(JSON.stringify(returnValue));
					} else{
						returnValue.msg = result.xml.return_msg[0];
						returnValue.status = '102';
						res.end(JSON.stringify(returnValue));
					}
				} else{
					returnValue.msg = result.xml.return_msg[0];
					returnValue.status = '102';
					res.end(JSON.stringify(returnValue));
				}
			});
		}
	})
});
/*
 * 根据商户订单号out_trade_no 查询订单
 */
router.all('/jkyx/wxpay_orderQuery', function(req, res, next) { 
	var param = req.query || req.params; 
	var out_trade_no = param.out_trade_no;

	var nonce_str = getNonceStr();
	
	var bodyData = '<xml>';
	bodyData += '<appid>' + Wx_config.AppID + '</appid>';
	bodyData += '<mch_id>' + Wx_config.Mch_id + '</mch_id>';
	bodyData += '<nonce_str>' + nonce_str + '</nonce_str>';
	bodyData += '<out_trade_no>' + out_trade_no + '</out_trade_no>';
	
	var sign = orderQuerySign(
		Wx_config.AppID,
		Wx_config.Mch_id, 
		nonce_str,
		out_trade_no
	);
	bodyData += '<sign>' + sign + '</sign>';
	bodyData += '</xml>';
	
	var urlStr = 'https://api.mch.weixin.qq.com/pay/orderquery';
	request({
		url: urlStr,
		method: 'POST',
		body: bodyData
	}, function (error, response, body) {
		if (!error && response.statusCode == 200) {
			var returnValue = {};
			parseString(body, function (err, result) {
				if (result.xml.return_code[0] == 'SUCCESS' && result.xml.result_code[0] == 'SUCCESS') {
					returnValue.msg = '操作成功';
					returnValue.status = '100';
					returnValue.result = result;
				    res.end(JSON.stringify(returnValue));
				} else{
					returnValue.msg = result.xml.return_msg[0];
					returnValue.status = '102';
					returnValue.result = result;
					res.end(JSON.stringify(returnValue));
				}
			});
		}
	})
});
/*
 * 根据商户订单号out_trade_no 关闭订单
 */
router.all('/jkyx/wxpay_closeOrder', function(req, res, next) {
	var param = req.query || req.params; 
	var out_trade_no = param.out_trade_no || '';
	if (out_trade_no == '') {
		res.end(JSON.stringify({
 			msg: '请传入商户订单号',
 			status:'101',
 		}));
 		return;
	}

	var nonce_str = getNonceStr();
	
	var bodyData = '<xml>';
	bodyData += '<appid>' + Wx_config.AppID + '</appid>';
	bodyData += '<mch_id>' + Wx_config.Mch_id + '</mch_id>';
	bodyData += '<nonce_str>' + nonce_str + '</nonce_str>';
	bodyData += '<out_trade_no>' + out_trade_no + '</out_trade_no>';
	
	var sign = orderQuerySign(
		Wx_config.AppID,
		Wx_config.Mch_id, 
		nonce_str,
		out_trade_no
	);
	bodyData += '<sign>' + sign + '</sign>';
	bodyData += '</xml>';
	
	var urlStr = 'https://api.mch.weixin.qq.com/pay/closeorder';
	request({
		url: urlStr,
		method: 'POST',
		body: bodyData
	}, function (error, response, body) {
		if (!error && response.statusCode == 200) {
			var returnValue = {};
			parseString(body, function (err, result) {
				if (result.xml.return_code[0] == 'SUCCESS' && result.xml.result_code[0] == 'SUCCESS') {
					returnValue.msg = '操作成功';
					returnValue.status = '100';
					returnValue.result = result;
				    res.end(JSON.stringify(returnValue));
				} else{
					returnValue.msg = result.xml.return_msg[0];
					returnValue.status = '102';
					returnValue.result = result;
					res.end(JSON.stringify(returnValue));
				}
			});
		}
	})
});
/*
 * PC端根据商户订单号out_trade_no 申请退款
 */
router.all('/jkyx/pc/wxpay_refundOrder', function(req, res, next) {
	var param = req.query || req.params; 
	var out_trade_no = param.out_trade_no || '';
	var account_id = param.account_id || '';
	var coupon_id = param.coupon_id || '';
	
	if (out_trade_no == '' || account_id == '') {
		res.end(JSON.stringify({
 			msg: '请传入正确的参数',
 			status:'102',
 		}));
 		return;
	}
	pool.getConnection(function(err, connection) {
		if(err){
			res.end(JSON.stringify({
     			msg: '数据库连接失败',
     			status:'101',
     		}));
		}
		connection.query(DBConfig.getRefundOrder,[out_trade_no,out_trade_no,account_id],function (err, results) {
//			connection.release();
			if (err){
			  	res.end(JSON.stringify({
	     			msg: '数据库查询失败',
	     			status:'102',
	     			err: err
	     		}));
			}else{
				var order_status = results[0][0].order_status;
				if (order_status == 7) {
					res.end(JSON.stringify({
		     			msg: '订单已经退款，请忽重复操作',
		     			status:'103'
		     		}));
		     		return;
				}
				// 余额支付金额
				var recharge_pay_amount = results[0][0].recharge_pay_amount;
				// 微信支付金额
				var pay_amount_other = results[0][0].pay_amount_other;
				// 账户余额
				var balance = Number(results[2][0].balance);
				var pay_timer = CommonJS.getNowFormatDate();
				// 没有使用微信支付
				if (pay_amount_other == 0) {
					balance = balance + recharge_pay_amount;
					// 账户充值
					connection.query(DBConfig.updateBalance,[balance,account_id,account_id,recharge_pay_amount,2,pay_timer],function (err, results) {
						connection.release();
						if (err){
						  	res.end(JSON.stringify({
				     			msg: '数据库查询失败',
				     			status:'102',
				     			err: err
				     		}));
						}else{
							res.end(JSON.stringify({
				     			msg: '退款成功',
				     			status:'100'
				     		}));
						}
					})
				} else{ // 有使用微信支付
					if (recharge_pay_amount == 0) {  // 全部微信支付
						wxpay_refundOrder(pay_amount_other,res,out_trade_no);
					} else{ // 混合支付
						balance = balance + recharge_pay_amount;
						// 账户充值
						connection.query(DBConfig.updateBalance,[balance,account_id,account_id,recharge_pay_amount,2,pay_timer],function (err, results) {
							connection.release();
							if (err){
							  	res.end(JSON.stringify({
					     			msg: '数据库查询失败',
					     			status:'102',
					     			err: err
					     		}));
							}else{
								wxpay_refundOrder(pay_amount_other,res,out_trade_no);
							}
						})
					}
					
				}
			}
		})
	})
});

/*
 * 测试充值退款 根据商户订单号out_trade_no 申请退款
 */
router.all('/jkyx/wx/wxpay_refundOrder', function(req, res, next) {
	var param = req.query || req.params; 
	var out_trade_no = param.out_trade_no || '';
	wxpay_refundOrder(1,res,out_trade_no);
})

function wxpay_refundOrder(fee,res,out_trade_no){
	var nonce_str = getNonceStr();
	fee = 1;
	var bodyData = '<xml>';
	bodyData += '<appid>' + Wx_config.AppID + '</appid>';
	bodyData += '<mch_id>' + Wx_config.Mch_id + '</mch_id>';
	bodyData += '<nonce_str>' + nonce_str + '</nonce_str>';
	bodyData += '<op_user_id>' + Wx_config.Mch_id + '</op_user_id>';
	bodyData += '<out_refund_no>' + out_trade_no + '</out_refund_no>';
	bodyData += '<out_trade_no>' + out_trade_no + '</out_trade_no>';
	bodyData += '<refund_fee>' + fee + '</refund_fee>';
	bodyData += '<total_fee>' + fee + '</total_fee>';
	 
	var sign = refundOrderSign(
		Wx_config.AppID,
		Wx_config.Mch_id,
		nonce_str,
		Wx_config.Mch_id,
		out_trade_no,
		out_trade_no,
		fee,
		fee
	);
		
	bodyData += '<sign>' + sign + '</sign>';
	bodyData += '</xml>';
	
	var agentOptions = {
		pfx: fs.readFileSync('./wx_config/apiclient_cert.p12'),
		passphrase: Wx_config.Mch_id,
	};
	var urlStr = 'https://api.mch.weixin.qq.com/secapi/pay/refund';
	request({
		url: urlStr,
		method: 'POST',
		body: bodyData,
		agentOptions: agentOptions
	}, function (error, response, body) {
		if (!error && response.statusCode == 200) {
			var returnValue = {};
			parseString(body, function (err, result) {
				if (result.xml.return_code[0] == 'SUCCESS' && result.xml.result_code[0] == 'SUCCESS') {
					returnValue.msg = '操作成功';
					returnValue.status = '100';
					returnValue.result = result;
				    res.end(JSON.stringify(returnValue));
				} else{
					returnValue.msg = result.xml.return_msg[0];
					returnValue.status = '102';
					returnValue.result = result;
					res.end(JSON.stringify(returnValue));
				}
			});
		}else{
			res.end(JSON.stringify({
				msg: "请求失败",
				status: "103"
			}));
		}
	})
}

/*
 * 根据商户订单号out_trade_no 查询退款
 */
router.all('/api/wxpay_refundQuery', function(req, res, next) {
	var param = req.query || req.params; 
	var out_trade_no = param.out_trade_no;
//	console.log('out_trade_no = ' + out_trade_no);

	var nonce_str = getNonceStr();
	var fee = '1';
	
	var bodyData = '<xml>';
	bodyData += '<appid>' + Wx_config.AppID + '</appid>';
	bodyData += '<mch_id>' + Wx_config.Mch_id + '</mch_id>';
	bodyData += '<nonce_str>' + nonce_str + '</nonce_str>';
	bodyData += '<out_trade_no>' + out_trade_no + '</out_trade_no>';
	 
	var sign = refundQuerySign(
		Wx_config.AppID,
		Wx_config.Mch_id,
		nonce_str,
		out_trade_no
	);
		
	bodyData += '<sign>' + sign + '</sign>';
	bodyData += '</xml>';

	var urlStr = 'https://api.mch.weixin.qq.com/pay/refundquery';
	request({
		url: urlStr,
		method: 'POST',
		body: bodyData,
	}, function (error, response, body) {
		if (!error && response.statusCode == 200) {
			var returnValue = {};
			parseString(body, function (err, result) {
				if (result.xml.return_code[0] == 'SUCCESS' && result.xml.result_code[0] == 'SUCCESS') {
					returnValue.msg = '操作成功';
					returnValue.status = '100';
					returnValue.result = result;
				    res.end(JSON.stringify(returnValue));
				} else{
					returnValue.msg = result.xml.return_msg[0];
					returnValue.status = '102';
					returnValue.result = result;
					res.end(JSON.stringify(returnValue));
				}
			});
		}else{
			res.end(JSON.stringify({
				msg: "请求失败",
				status: "103"
			}));
		}
	})
});


/*
 * 微信支付回调
 */
router.all('/api/wxpay', function(req, res, next) {
	var body = req.body;
	console.log(body);
});

// 生成32位的随机字符串
function getNonceStr(){
	var len = 32;
　　var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';    
　　var maxPos = chars.length;
　　var pwd = '';
　　for (i = 0; i < len; i++) {
　　　　pwd += chars.charAt(Math.floor(Math.random() * maxPos));
　　}
　　return pwd;
}
function paysignjs(appid, nonceStr, package, signType, timeStamp) {
    var ret = {
        appId: appid,
        nonceStr: nonceStr,
        package: package,
        signType: signType,
        timeStamp: timeStamp
    };
    var str = raw1(ret);
    str = str + '&key='+key;
    return cryptoMO.createHash('md5').update(str).digest('hex');
};

function raw1(args) {
    var keys = Object.keys(args);
    keys = keys.sort()
    var newArgs = {};
    keys.forEach(function(key) {
        newArgs[key] = args[key];
    });

    var str = '';
    for(var k in newArgs) {
        str += '&' + k + '=' + newArgs[k];
    }
    str = str.substr(1);
    return str;
};
// 生成签名
function paysignjsapi(appid,body,mch_id,nonce_str,notify_url,openid,out_trade_no,spbill_create_ip,total_fee) {
    var ret = {
        appid: appid,
        body: body,
        mch_id: mch_id,
        nonce_str: nonce_str,
        notify_url:notify_url,
        openid:openid,
        out_trade_no:out_trade_no,
        spbill_create_ip:spbill_create_ip,
        total_fee:total_fee,
        trade_type: 'JSAPI'
    };
    var str = raw(ret);
    str = str + '&key='+key;
    var md5Str = cryptoMO.createHash('md5').update(str).digest('hex');
    md5Str = md5Str.toUpperCase();
    return md5Str;
};
// 查询/关闭订单 签名算法 
function orderQuerySign(appid,mch_id,nonce_str,out_trade_no) {
    var ret = {
        appid: appid,
        mch_id: mch_id,
        nonce_str: nonce_str,
        out_trade_no: out_trade_no
    };
    var str = raw(ret);
    str = str + '&key='+key;
    var md5Str = cryptoMO.createHash('md5').update(str).digest('hex');
    md5Str = md5Str.toUpperCase();
    return md5Str;
};
// 订单退款 签名算法 
function refundOrderSign(appid,mch_id,nonce_str,op_user_id,out_refund_no,out_trade_no,refund_fee,total_fee) {
    var ret = {
        appid: appid,
        mch_id: mch_id,
        nonce_str: nonce_str,
        op_user_id: op_user_id,
        out_refund_no: out_refund_no,
        out_trade_no: out_trade_no,
        refund_fee: refund_fee,
        total_fee: total_fee
    };
    var str = raw(ret);
    str = str + '&key='+key;
    var md5Str = cryptoMO.createHash('md5').update(str).digest('hex');
    md5Str = md5Str.toUpperCase();
    return md5Str;
};

// 查询退款 签名算法 
function refundQuerySign(appid,mch_id,nonce_str,out_trade_no) {
    var ret = {
        appid: appid,
        mch_id: mch_id,
        nonce_str: nonce_str,
        out_trade_no: out_trade_no
    };
    var str = raw(ret);
    str = str + '&key='+key;
    var md5Str = cryptoMO.createHash('md5').update(str).digest('hex');
    md5Str = md5Str.toUpperCase();
    return md5Str;
};

function raw(args) {
    var keys = Object.keys(args);
    keys = keys.sort(); 
    var newArgs = {};
    keys.forEach(function(key) {
        newArgs[key.toLowerCase()] = args[key];
    });

    var str = '';
    for(var k in newArgs) {
        str += '&' + k + '=' + newArgs[k];
    }
    str = str.substr(1);
    return str;
};

module.exports = router;

